package org.bluedream.core.module.sys.service;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.commons.collections.map.HashedMap;
import org.bluedream.comm.base.BaseEntity;
import org.bluedream.comm.base.BaseServiceImpl;
import org.bluedream.comm.base.TreeServiceImpl;
import org.bluedream.comm.utils.StringUtils;
import org.bluedream.core.module.sys.config.service.ConfigService;
import org.bluedream.core.module.sys.dao.UserDao;
import org.bluedream.core.module.sys.entity.Menu;
import org.bluedream.core.module.sys.entity.Store;
import org.bluedream.core.module.sys.entity.User;
import org.bluedream.comm.utils.EmptyUtil;
import org.bluedream.comm.utils.EncryptUtil;
import org.bluedream.core.utils.PasswordHelper;
import org.bluedream.core.utils.SpringUtil;
import org.bluedream.core.utils.UserUtil;
import org.bluedream.core.utils.configUtil.GoalConfigUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import sun.nio.cs.US_ASCII;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@DS("master")
@Transactional(
        readOnly = true
)
public class UserService extends BaseServiceImpl<UserDao, User> implements IService<User> {
    private static final Logger logger = LoggerFactory.getLogger(UserService.class);

    @Resource
    private RoleService roleService;

    @Resource
    private ConfigService configService;

    @Resource
    private RoleRelationService roleRelationService;

    @Resource
    private MenuService menuService;

/*    public User getSystem(){
        return baseMapper.getSystem();
    }*/

    /**
     * 用于新增用户  密码强制赋值为默认初始密码
     * @param user
     * @return
     */
    @Override
    @Transactional(
            readOnly = false,
            rollbackFor = Exception.class
    )
    public boolean save(User user) {
        try {
            boolean isNewRecord = super.getIsNewRecord(user , "login_code" , "getLoginCode");
            user.setIsNewRecord(isNewRecord);
            // 如果是新增用户，密码处理
            if (isNewRecord){
                user.setPassword(PasswordHelper.encryptPassword(GoalConfigUtil.getValueByKey("sys.user.initPassword") , user.getLoginCode()));
            }
            return super.save(user);
        }catch (Exception e){
            e.printStackTrace();
            logger.error("保存用户信息失败，错误信息：" + e.getMessage());
            //todo:@Transactional和try catch捕获异常会让注解失效
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }

    public List<Map<String , Object>> treeData(String excludeCode , String isShowCode){
        try {
            List<Map<String , Object>> mapList = new ArrayList<>();
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("1" , "1");
            queryWrapper.apply("(create_by in(select login_code from v_sys_orgAndUser a where a.org_id = '"+ UserUtil.getLoginOrgCode() + "') " +
                    "       or login_code in(select login_code from v_sys_orgAndUser a where a.org_id = '"+ UserUtil.getLoginOrgCode() + "')) " );
            List<User> list = super.list(queryWrapper);
            for (User c1:list
            ) {
                if (!BaseEntity.STATUS_NORMAL.equals(c1.getStatus())){
                    continue;
                }
                if (EmptyUtil.isNoEmpty(excludeCode)){
                    if (c1.getId().equals(excludeCode)){
                        continue;
                    }
                }
                Map<String , Object> map = new HashMap<>();
                String id = c1.getId();

                map.put("id" , id);
                map.put("pId" , "0");
                map.put("code" , c1.getLoginCode());
                map.put("name" , StringUtils.getTreeNodeName(isShowCode , c1.getLoginCode() , c1.getUserName()));
                map.put("isTreeLeaf" , true);
                map.put("isParent" , false);
                mapList.add(map);
            }
            return mapList;
        }catch (Exception e1){
            e1.printStackTrace();
        }
        return null;
    }

    @Transactional(
            readOnly = false,
            rollbackFor = Exception.class
    )
    public boolean resetPassword(User user){
        try {
            user.setPassword(PasswordHelper.encryptPassword(GoalConfigUtil.getValueByKey("sys.user.initPassword") , user.getLoginCode()));
            return super.save(user);
        }catch (Exception e){
            logger.error("重置密码失败，错误信息：" + e.getMessage());
            //todo:@Transactional和try catch捕获异常会让注解失效
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }

    @Transactional(
            readOnly = false,
            rollbackFor = Exception.class
    )
    public boolean modifyPassword(String pwd){
        try {
            User user = UserUtil.getLoginInfo();
            pwd = EncryptUtil.decodeBase64String(pwd);
            user.setPassword(PasswordHelper.encryptPassword(pwd , user.getLoginCode()));
            return super.updateById(user);
        }catch (Exception e){
            logger.error("用户密码修改失败，错误信息：" + e.getMessage());
            //todo:@Transactional和try catch捕获异常会让注解失效
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }

    public boolean isLogin(User user){
        if (EmptyUtil.isEmpty(user.getLoginCode())){
            return false;
        }
        User checkUser = getUserByLoginCode(user);
        String pwd = EncryptUtil.encodeMD5String(user.getPassword());
        if (EmptyUtil.isEmpty(checkUser)){
            return false;
        }else if (checkUser.getPassword().equals(pwd)){
            return true;
        }
        return false;
    }

    private User getUserByLoginCode(User user){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (EmptyUtil.isEmpty(user)){
            return null;
        }
        queryWrapper.eq("login_Code" , user.getLoginCode());
        return super.getOne(queryWrapper);
    }

    @Override
    public User getById(Serializable id) {
        return EmptyUtil.isEmpty(id)?new User():super.getById(id);
    }

    public IPage<User> findPage(User entity, String... args){
        long current = EmptyUtil.isEmpty(entity.getPage())?1L:entity.getPage();
        long size = EmptyUtil.isEmpty(entity.getLimit())?10L:entity.getLimit();

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("1" , "1");
        if (!UserUtil.isSystem()){
            queryWrapper.apply("(create_by in(select login_code from v_sys_orgAndUser a where a.org_id = '"+ UserUtil.getLoginOrgCode() + "') " +
                    "       or login_code in(select login_code from v_sys_orgAndUser a where a.org_id = '"+ UserUtil.getLoginOrgCode() + "')) " );
        }
        if (EmptyUtil.isNoEmpty(entity.getUserName())){
            queryWrapper.like("user_name" , entity.getUserName());
        }
        if (EmptyUtil.isNoEmpty(entity.getLoginCode())){
            queryWrapper.like("login_code" , entity.getLoginCode());
        }

        queryWrapper.orderByAsc(args);
        return super.page(new Page<User>(current , size) , queryWrapper);
    }

/*    public IPage<User> findPage(User entity, String... args) {
        Map<String , Object> search = null;
        if (EmptyUtil.isNoEmpty(entity.getUserName())
                || EmptyUtil.isNoEmpty(entity.getLoginCode())
        ){
            search = new HashedMap();
            if (EmptyUtil.isNoEmpty(entity.getUserName())){
                search.put("USER_NAME" , entity.getUserName());
            }
            if (EmptyUtil.isNoEmpty(entity.getLoginCode())){
                search.put("LOGIN_CODE" , entity.getLoginCode());
            }
        }else {
            long limit = entity.getLimit();
            long page = entity.getPage();
            entity = new User();
            entity.setLimit(limit);
            entity.setPage(page);
        }
        return super.findPage(entity , search , args);
    }*/

    public IPage<User> findPageChecked(User user , String searchId , String type) {
        try {
            IPage<User> page = this.findPage(user);
            List<User> checkedUsers = new ArrayList<>();
            if (type.equals("role")){
                checkedUsers = baseMapper.getUsersByRoleIdOfIsChecked(searchId);
            }else if (type.equals("depItem")){
                checkedUsers = baseMapper.getUsersByDepItemIdOfIsChecked(searchId);
            }

            if (EmptyUtil.isEmpty(checkedUsers)){
                return page;
            }else {
                List<User> pageList = page.getRecords();
                List<User> getPageList = new ArrayList<>();
                for (User u1:pageList
                     ) {
                    boolean flag = false;
                    for (User u2:checkedUsers
                         ) {
                        if (u1.getId().equals(u2.getId())){
                            flag = true;
                            break;
                        }
                    }
                    if (flag){
                        u1.setIsChecked(true);
                    }else {
                        u1.setIsChecked(false);
                    }
                    getPageList.add(u1);
                }
                page.setRecords(getPageList);
            }
            return page;
        }catch (Exception e){
            logger.error("查询角色授权用户失败，错误信息：" + e.getMessage());
            return null;
        }
    }

    public boolean checkPassword(String pwd){
            User user = UserUtil.getLoginInfo();
            pwd = PasswordHelper.encryptPassword(pwd , user.getLoginCode());
        if (user.getPassword().equals(pwd)){
            return true;
        }
        return false;
    }


    /**
     * 返回登录用户的菜单数据
     * 1. 如果是系统管理员登录，则返回所有菜单
     * 2. 非系统管理员
     * @return
     */
    public List<Map<String , Object>> getMenuTreeData(){
        return menuService.getMenuTreeDataByLoginUserAndOrg(0);
    }
}
